package com.kemai.customize

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.core.view.marginTop
import java.util.ArrayList
import kotlin.math.max

/**

 *@description: 自定义流式布局
 * @author: zhaoshanshan
 * @date: 2022/11/20 8:00 下午

 */
class FlowLayout:ViewGroup{

    private var mLineViews: MutableList<View>? = null //每一行的子View

    private var mViews: MutableList<List<View>?>? = null //所有的行 一行一行的存储

    private var mHeights  : MutableList<Int>? = null//每一行的高度


    constructor(context: Context):this(context,null){}
    constructor(context: Context, attrs: AttributeSet?):this(context,attrs,0){}
    constructor(context: Context, attrs: AttributeSet?,defaultStyle:Int) : super(context,attrs,defaultStyle) {
        init()
    }

    private fun init() {
        mLineViews = ArrayList()
        mViews = ArrayList()
        mHeights = ArrayList()
    }
    //需要重写此方法才能使用MarginLayoutParams
    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context,attrs)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        // 获取限制的值
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec) // MeasureSpec.UNSPECIFIED
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)


//        heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize,MeasureSpec.EXACTLY);

        // 记录当前行的宽度和高度
        var lineWidth = 0 // 宽度是当前行子view的宽度之和
        var lineHeight = 0 // 高度是当前行所有子View中高度的最大值

        //整个流式布局的宽度和高度
        var flowLayoutWidth = 0 //所有行中宽度的最大值
        var flowLayoutHeight = 0 // 所以行的高度的累加
        init()

        // 获取FlowLayout的padding
        val paddingLeftRight = paddingLeft + paddingRight
        val paddingTopBottom = paddingTop + paddingBottom
        val childCount = this.childCount

        // 先测量子View，再根据子View尺寸，计算自己的
        for (i in 0 until childCount) {
            val child = getChildAt(i)
            //measureChild(child, widthMeasureSpec, heightMeasureSpec)
            measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0) //处理子控件的view的边距问题
            val lp = child.layoutParams as MarginLayoutParams
            val childMarginLeftRight = lp.leftMargin + lp.rightMargin;
            val childMarginTopBottom = lp.topMargin + lp.bottomMargin;

            //获取到当前子View的测量的宽度/高度
            val childWidth = child.measuredWidth
            val childHeight = child.measuredHeight

            // 已经放入的孩子的宽度 + 准备放入的孩子的宽度 大于 总宽度 就换行
            if (lineWidth + childWidth+paddingLeftRight+childMarginLeftRight > widthSize) {
                mViews!!.add(mLineViews)
                mLineViews = ArrayList() //创建新的一行
                // 所有行中 最宽的一行 作为 流式布局的宽
                flowLayoutWidth = max(flowLayoutWidth, lineWidth)
                // 流式布局的高度为所有行的高度相加
                flowLayoutHeight += lineHeight
                mHeights!!.add(lineHeight)
                lineWidth = 0
                lineHeight = 0
            }
            mLineViews!!.add(child)
            lineWidth += childWidth+childMarginLeftRight

            // 获取行中最高的子View
            lineHeight = max(lineHeight, childHeight+childMarginTopBottom)

            // 处理最后一行的显示
            if (i == childCount - 1) {
                flowLayoutHeight += lineHeight
                flowLayoutWidth = max(flowLayoutWidth, lineWidth)
                mHeights!!.add(lineHeight)
                mViews!!.add(mLineViews)
            }
        }

        flowLayoutWidth += paddingLeftRight;
        flowLayoutHeight += paddingTopBottom;

        // 保存尺寸给后面用
        setMeasuredDimension(
            if (widthMode == MeasureSpec.EXACTLY) widthSize else flowLayoutWidth,
            if (heightMode == MeasureSpec.EXACTLY) heightSize else flowLayoutHeight
        )
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var currX = paddingLeft
        var currY = paddingTop
        val lineCount = mViews!!.size
        // 处理每一行
        for (i in 0 until lineCount) {
            val lineViews = mViews!![i]
            val lineHeight = mHeights!![i]
            val size = lineViews!!.size
            // 处理每一行中的View
            for (j in 0 until size) {
                val child = lineViews[j]
                val lp = child.layoutParams as MarginLayoutParams
                // 子View的左上右下
                val left = currX+lp.leftMargin
                val top = currY+lp.topMargin
                val right = left + child.measuredWidth
                val bottom = top + child.measuredHeight
                // 布局子View
                child.layout(left, top, right, bottom)
                currX += right+lp.rightMargin
            }
            currY += lineHeight
            currX = paddingLeft
        }
    }
}